package org.lex.game.sudoku.util;

import java.awt.EventQueue;
import java.lang.reflect.InvocationTargetException;

import javax.swing.SwingUtilities;

import org.lex.game.sudoku.model.solver.Decision;
import org.lex.game.sudoku.model.solver.SolverObserver;

public class SyncSolverObserver implements SolverObserver {
	private final SolverObserver delegate;

	public SyncSolverObserver(SolverObserver delegate) {
		super();
		this.delegate = delegate;
	}

	public void beginDecision(final Decision decision) {
		run(new Runnable() {
			@Override
			public void run() {
				delegate.beginDecision(decision);
			}
		});
	}

	public void fillCell(final int row, final int col, final int num) {
		run(new Runnable() {
			@Override
			public void run() {
				delegate.fillCell(row, col, num);
			}
		});
	}

	public void rollbackDecision(final Decision decision, final int cellCount) {
		run(new Runnable() {
			@Override
			public void run() {
				delegate.rollbackDecision(decision, cellCount);
			}
		});
	}

	@Override
	public void reset() {
		run(new Runnable() {
			@Override
			public void run() {
				delegate.reset();
			}
		});
	}

	private void run(Runnable run) {
		if (EventQueue.isDispatchThread()) {
			run.run();
		} else {
			try {
				SwingUtilities.invokeAndWait(run);
			} catch (InvocationTargetException | InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}
